<template>
  <div class="loginForm">
    <div class="rloginTitle">{{ formTitle }}</div>

    <!-- 各个输入框 -->
    <el-form :model="formData" :rules="formRules" ref="formRef" label-width="50px">
      <el-form-item v-for="(item) in props.customFields.inputData" :key="item" :prop="item.lable" >
        <div class="formInput">
          <el-input v-if="item.type !== 'password'" v-model="formData[item.lable]" :placeholder="item.inputPlaceholder"
            clearable :type="item.type" autocomplete="off"
            :prefix-icon="item.icon === Icons.USER ? User : (item.icon === Icons.IPHONE ? Iphone : (item.icon === Icons.VERIFY ? Edit : ''))"></el-input>

          <el-input v-else v-model="formData[item.lable]" :placeholder="item.inputPlaceholder" :type="item.type"
            show-password autocomplete="off" :prefix-icon="Lock"></el-input>
        </div>
      </el-form-item>

      <!-- 验证码 -->
      <el-form-item v-if="props.customFields.type === GoPageName.LOGIN">
        <div class="formInput codeLine">
          <el-input class="codeInput" @input="checkCodeFun" v-model="checkCode.code" placeholder="输入验证码" clearable
            maxlength="4" />
          <slideVerify class="codeShow" v-model:identifyCode="identifyCode" @click="refresh()"></slideVerify>
        </div>
      </el-form-item>

      <!-- 咨询者注册界面 -->
      <el-form-item v-if="props.customFields.type === GoPageName.REGISTERCLIENT">
        <div class="formInput settings">
          <label></label>
          <label class="labelText">
            <span @click.stop="go_page(GoPageName.LOGIN)">去登录</span>
          </label>
        </div>
      </el-form-item>

      <!-- 咨询师注册界面 -->
      <el-form-item v-if="props.customFields.type === GoPageName.REGISTERcounselor">
        <div class="formInput settings">
          <label></label>
          <label class="labelText">
            <span @click.stop="go_page(GoPageName.LOGIN)">去登录</span>
          </label>
        </div>
      </el-form-item>

      <!-- 登陆界面 -->
      <el-form-item v-if="props.customFields.type === GoPageName.LOGIN">
        <div class="formInput settings">
          <label class="labelText">
            <input type="checkbox" v-model="rem_pswd" /> 记住密码
          </label>
          <label class="labelText">
            <span @click.stop="go_page(GoPageName.REGISTERCLIENT)">咨询者注册</span>
          </label>
          <label class="labelText">
            <span @click.stop="go_page(GoPageName.REGISTERcounselor)">咨询师注册</span>
          </label>
        </div>
      </el-form-item>

      <!-- 修改密码 -->
      <el-form-item v-if="props.customFields.type === GoPageName.UPDATEPASSWORD">
        <div class="formInput settings">
          <label></label>
          <label class="labelText">
            <span @click.stop="go_page(GoPageName.PERSONALSETTING)">返回个人信息</span>
          </label>
        </div>
      </el-form-item>

      <!-- 提交按钮 -->
      <el-form-item label-width="0">
        <el-button :loading="loading" :disabled="props.customFields.type === GoPageName.LOGIN && !checkCode.isTrue"
          type="primary" class="loginButton" round @click="handleSubmita(formRef)">{{
            formBtntitle }}</el-button>
      </el-form-item>


    </el-form>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue';
import { ElMessage, ElMessageBox, ElNotification, FormInstance, FormRules } from 'element-plus';
import router from '@/router';
import { GoPageName, Icons } from "@/enums/index.ts" // 状态参数文件引入
import { Lock, User, Iphone, Edit } from '@element-plus/icons-vue'  // 文字图标
import SsoUserApi from '@/api/sso_user';
import type { RegisterParams } from '@/api/sso_user/type';
import { encryptedData } from '@/utils/jsencrypt';

// 使用该组件的页面 传递的参数类型定义
interface CustomFieldsType {
  title: string,
  btnTitle: string,
  type: string,
  inputData: Array<any>,
  rules: Array<Object>
}
const props = defineProps({
  // 接收自定义参数内容
  customFields: {
    type: Object as () => CustomFieldsType, // 将类型设置为 CustomFieldsType
    required: true,
  },
  // 接收 点击事件 执行函数
  handleSubmit: {
    type: Function,
    required: true
  }
});
// 记住密码，true 或 false
const rem_pswd = ref(localStorage.getItem('rem_pswd'))

const formTitle: string = props.customFields.title // 该组件标题设置
const formBtntitle = ref<string>(props.customFields.btnTitle) // 该组件按钮设置,仅支持一个按钮

const formRef = ref<FormInstance>(); // 创建一个 ref 来引用表单

// 修改密码 检验规则 要放在 formRules 之前
const validatePass = (_rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('Please input the password'))
  } else {
    if (formData.newPassword !== '') {
      if (!formRef.value) return
      formRef.value.validateField('checkPass', () => null)
    }
    callback()
  }
}
const checkPass = (_rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请确认密码'))
  } else if (value !== formData.inputPassword) {
    console.log(formData.inputPassword,value)
    callback(new Error("两次输入的密码不一致"))
  } else {
    callback()
  }
}
const confirmPass = (_rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请确认密码'))
  } else if (value !== formData.inputPassword) {
    console.log(formData.inputPassword,value)
    callback(new Error(`两次输入的密码不一致`))
  } else {
    callback()
  }
}

const formData = reactive(createFormData(props.customFields)); // 使用 reactive 创建响应式对象，用于存储表单数据
const formRules = reactive<FormRules>(createFormRules(props.customFields)); // 使用 reactive 创建响应式对象，用于存储表单验证规则

// 创建表单数据对象
function createFormData(customFields: CustomFieldsType) {
  const data: { [key: string]: any } = {};
  customFields.inputData.forEach((item: any) => {
    data[item.lable] = item.value;
  })
  // 判断是否记住密码
  if (rem_pswd.value) {
    data.account = localStorage.getItem('account')
    data.password = localStorage.getItem('password')
  }
  // console.log('data',data);
  return data;
}

// 创建表单验证规则对象
function createFormRules(customFields: CustomFieldsType) {
  const rules: { [key: string]: any } = {};
  customFields.inputData.forEach((item: any, index) => {
    rules[item.lable] = customFields.rules[index] || [];
  })
  if (customFields.type === GoPageName.UPDATEPASSWORD) {
    rules.newPassword[0].validator = validatePass
    rules.checkPassword[0].validator = checkPass
  }
  if (customFields.type === GoPageName.REGISTERCLIENT) {
    rules.ConfirmPassword[0].validator = confirmPass
  }
  return rules;
}

const go_page = (type: string) => {
  switch (type) {
    case GoPageName.LOGIN:
    case GoPageName.FINDPASSWORD:
    case GoPageName.UPDATEPASSWORD:
    case GoPageName.REGISTERCLIENT:
    case GoPageName.REGISTERcounselor:
      router.push({
        name: GoPageName.LOGIN, // 这几个页面的路由都是login，根据path判断显示
        params: {
          path: type
        }
      });
      break
    case GoPageName.PERSONALSETTING:
      router.push({
        name: GoPageName.PERSONALSETTING, // 替换为目标路由的名称或路径
        params: {
          path: GoPageName.PERSONALINFO
        }
      });
      break;
    default:
      console.log('not fond url', type);
      break
  }

  // console.log(appStore.type);
}

// 按钮的加载状态
const loading = ref(false)
import { useUserInfoStore } from '@/stores/info/index' // 登陆状态获取，全局变量
const userInfoStore = useUserInfoStore();
import { navBarSelectState } from '@/stores/info/index' // 页面状态获取，全局变量
const selectedBar = navBarSelectState()
// 按钮点击事件
const handleSubmita = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  
  formEl.validate(async (valid, fields) => {
    if (valid) {
      loading.value = true;
      
      try {
        if (props.customFields.type === GoPageName.REGISTERCLIENT) {
          // 检查密码一致性
          if (formData.inputPassword !== formData.ConfirmPassword) {
            ElMessage.error('两次输入的密码不一致');
            loading.value = false;
            return;
          }
          const encryptedPassword = encryptedData(formData.inputPassword.toString());
          if (typeof encryptedPassword !== 'string') {
            throw new Error('密码加密失败');
          }
          // 构造注册数据
          const registerData: RegisterParams = {
            account: formData.mobile,
            password: encryptedPassword,
            name: formData.name, // 初始名称与账号相同
            gender: formData.gender === '男' ? 1 : 2,
            user_type: 1, // 1表示咨询者
            mobile: formData.mobile,
            email: formData.email
          };

          // 调用注册接口
          const res = await SsoUserApi.register(registerData);
          if (res) {
            ElMessage({
              type: 'success',
              message: '注册成功，即将跳转到登录页面',
              duration: 2000
            });
            
            // 延迟跳转到登录页
            setTimeout(() => {
              router.push({
                name: GoPageName.LOGIN, // 这几个页面的路由都是login，根据path判断显示
                params: {
                  path: GoPageName.LOGIN
                }
              });
            }, 2000);
          } else {
            ElMessage.error('注册失败');
          }
        } else if (props.customFields.type === GoPageName.REGISTERcounselor) {
          const encryptedPassword = encryptedData(formData.inputPassword.toString());
          if (typeof encryptedPassword !== 'string') {
            throw new Error('密码加密失败');
          }
          // 构造注册数据
          const registerData: RegisterParams = {
            account: formData.phoneNomber,
            password: encryptedPassword,
            name: formData.username, // 初始名称与账号相同
            gender: formData.gender === '男' ? 1 : 2,
            mobile: formData.phoneNomber,
            email: formData.email,
            user_type: 2, // 2表示咨询师
            certificate: formData.qualification,
            level: formData.level,
          };

          // 调用注册接口
          const res = await SsoUserApi.register(registerData);
          if (res) {
            ElMessage({
              type: 'success',
              message: '注册成功，即将跳转到登录页面',
              duration: 2000
            });
            
            // 延迟跳转到登录页
            setTimeout(() => {
              router.push({
                name: GoPageName.LOGIN, // 这几个页面的路由都是login，根据path判断显示
                params: {
                  path: GoPageName.LOGIN
                }
              });
            }, 2000);
          } else {
            ElMessage.error('注册失败');
          }
        }
        else if (props.customFields.type === GoPageName.LOGIN) {
          setTimeout(async () => {
            // 记录是否选中密码
            if (rem_pswd.value) {
              localStorage.setItem('rem_pswd', 'true')
              localStorage.setItem('account', formData.account)
              localStorage.setItem('password', formData.password)
            } else {
              localStorage.setItem('rem_pswd', 'false')
              localStorage.setItem('account', "")
              localStorage.setItem('password', "")
            }
            props.handleSubmit(formData).then((res: any) => {
              console.log(res);
              router.push({
                name: 'index',
                params: { path: 'index' }
            })  
              selectedBar.setSelected(0)
            }).catch((err: any) => {
              console.log(err);
              checkCode.code = ""
              refresh()
              ElNotification({
                title: 'Error',
                message: `出现错误 ${err}`,
                type: 'error',
              })
            })
            loading.value = false

          }, 1000)
        }
        else if (props.customFields.type === GoPageName.UPDATEPASSWORD) {
          ElMessageBox.confirm(
            '确认修改密码? 修改成功后，将退出登录，需要重新进行登录！请记好密码！',
            '提示',
            {
              confirmButtonText: '确认',
              cancelButtonText: '取消',
              type: 'warning',
            }
          )
            .then(() => {
              ElMessage({
                type: 'success',
                message: '修改成功',
              })
              setTimeout(() => {
                userInfoStore.setIsLogin(false)
                Cookie.removeCookies('token')
                // Cookie.removeCookies('account')
                Session.clear()
              }, 1000)
            })
            .catch(() => {
              ElMessage({
                type: 'info',
                message: '修改失败',
              })
            })
          loading.value = false

        }
      } catch (error: any) {
        console.error('操作失败:', error);
        ElMessage.error(error.message || '操作失败');
      } finally {
        loading.value = false;
      }
    } else {
      console.log('表单验证失败:', fields);
    }
  });
};

// 生成验证码以及检测
import slideVerify from "./slideVerify.vue"
import { Cookie, Session } from '@/utils/cookieSet';
interface CheckCodeType {
  code: string;
  isTrue: boolean;
}
// 生成随机验证码
const generateCode = () => {
  const code = ref('');
  const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
  for (let i = 0; i < 4; i++) {
    code.value += characters.charAt(Math.floor(Math.random() * characters.length));
  }
  return code.value;
}
// 传递 验证码给子组件
const identifyCode = ref(generateCode())
// 刷新验证码
const refresh = () => {
  identifyCode.value = generateCode()
}
// 检测输入的验证码，控制提交按钮是否可用
const checkCodeFun = (newValue: string) => {
  if ((newValue as string).toUpperCase() === identifyCode.value) {
    checkCode.isTrue = true
  } else {
    checkCode.isTrue = false
  }
}
const checkCode = reactive<CheckCodeType>({
  code: identifyCode.value.substring(0,3),
  isTrue: false
})
</script>


<style scoped>
/* 可以添加一些样式 */
.loginForm {
  height: 400px;
  border: 1px solid;
  border-radius: 10px;
  text-align: center;
  background-color: #f3f3f3;
}

.loginForm .rloginTitle {
  font-size: 23px;
  margin: 5%;
}

.loginButton {
  width: 250px;
  margin: auto;
  margin-top: 20px;
}

.formInput {
  width: 80%;
  min-width: 50px;
}

.codeLine {
  display: flex;
}

.codeLine .codeInput {
  flex: 2;

}

.codeLine .codeShow {
  flex: 1;

}

.settings {
  display: flex;
  justify-content: space-between;
}

.settings label {
  flex: 1;
  font-size: 16px;
}

.settings .labelText {
  cursor: pointer;
}

.btn-base {
  width: 100%;
}

.btn-flex {
  display: flex;
  justify-content: center;
}

:deep(.el-form-item) {
  margin-bottom: 10px;
  margin-top: 0px;
}

:deep(.rloginTitle) {
  margin-bottom: 10px;
}
</style>
